package com.example.wp_test;

import android.content.Context;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * File: GpioHelper.java
 * Author: mine
 * Create: 2025/7/15 19:44
 * Changes (from 2025/7/15)
 */
public class GpioHelper {
    private static final String TAG = "PCIE_GPIO_IN_OUT_TEST";

    public static final String GPIO_BASE_PATH = "/sys/devices/platform/gpio-ctl/";

    // 生成输出gpio value节点路径
    public static String getGpioOutValuePath(int idx) {
        String path = GPIO_BASE_PATH + "gpio_out" + idx + "/value";
        Log.d(TAG, "getGpioOutValuePath: idx=" + idx + " -> " + path);
        return path;
    }

    // 生成输入gpio value节点路径
    public static String getGpioInValuePath(int idx) {
        String path = GPIO_BASE_PATH + "gpio_in" + idx + "/value";
        Log.d(TAG, "getGpioInValuePath: idx=" + idx + " -> " + path);
        return path;
    }

    // 写sysfs
    public static boolean writeSysfs(String path, String val) {
        File file = new File(path);
        if (!file.isFile()) {
            Log.w(TAG, "writeSysfs: 文件不存在 " + path);
            return false;
        }
        try (FileWriter fw = new FileWriter(file)) {
            fw.write(val);
            Log.i(TAG, "writeSysfs: 写入成功 " + path + " value=" + val);
            return true;
        } catch (IOException e) {
            Log.e(TAG, "writeSysfs: 写入异常 " + path + " value=" + val, e);
            return false;
        }
    }

    // 读sysfs
    public static String readSysfs(String path) {
        File file = new File(path);
        if (!file.isFile()) {
            Log.w(TAG, "readSysfs: 文件不存在 " + path);
            return null;
        }
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line = br.readLine();
            Log.d(TAG, "readSysfs: " + path + " value=" + line);
            return line;
        } catch (IOException e) {
            Log.e(TAG, "readSysfs: 读取异常 " + path, e);
            return null;
        }
    }

    // 一键拉高所有输出
    public static void setAllOutHigh(Context context, TextView tvResult, int outputCount) {
        boolean allSuccess = true;
        List<Integer> failList = new ArrayList<>();
        for (int i = 1; i <= outputCount; i++) {
            String path = getGpioOutValuePath(i);
            boolean ok = writeSysfs(path, "1");
            if (!ok) {
                allSuccess = false;
                failList.add(i);
            }
        }
        String msg = allSuccess
                ? "所有输出GPIO已拉高 (LED应全亮)"
                : "有" + failList.size() + "路输出GPIO拉高失败: " + failList;
        Log.i(TAG, "setAllOutHigh: " + msg);
        tvResult.setText(msg);
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }

    // 一键拉低所有输出
    public static void setAllOutLow(Context context, TextView tvResult, int outputCount) {
        boolean allSuccess = true;
        List<Integer> failList = new ArrayList<>();
        for (int i = 1; i <= outputCount; i++) {
            String path = getGpioOutValuePath(i);
            boolean ok = writeSysfs(path, "0");
            if (!ok) {
                allSuccess = false;
                failList.add(i);
            }
        }
        String msg = allSuccess
                ? "所有输出GPIO已拉低 (LED应全灭)"
                : "有" + failList.size() + "路输出GPIO拉低失败: " + failList;
        Log.i(TAG, "setAllOutLow: " + msg);
        tvResult.setText(msg);
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }

    // 检查所有输入
    public static void checkAllInput(Context context, TextView tvResult, int inputCount) {
        StringBuilder sb = new StringBuilder();
        boolean allLow = true;
        List<String> notLowList = new ArrayList<>();
        for (int i = 1; i <= inputCount; i++) {
            String path = getGpioInValuePath(i);
            String val = readSysfs(path);
            String nodeName = "gpio_in" + i;
            if (val == null) {
                sb.append(nodeName).append(": 读取失败\n");
                notLowList.add(nodeName);
                allLow = false;
                Log.w(TAG, "checkAllInput: " + nodeName + " 读取失败");
            } else if (!val.trim().equals("0")) {
                sb.append(nodeName).append(": 当前值=").append(val.trim()).append("\n");
                notLowList.add(nodeName);
                allLow = false;
                Log.i(TAG, "checkAllInput: " + nodeName + " = " + val.trim());
            }
        }
        String[] extraIns = {"gpio_ssr_in1", "gpio_ssr_in2"};
        for (String node : extraIns) {
            String path = GPIO_BASE_PATH + node + "/value";
            String val = readSysfs(path);
            if (val == null) {
                sb.append(node).append(": 读取失败\n");
                notLowList.add(node);
                allLow = false;
                Log.w(TAG, "checkAllInput: " + node + " 读取失败");
            } else if (!val.trim().equals("0")) {
                sb.append(node).append(": 当前值=").append(val.trim()).append("\n");
                notLowList.add(node);
                allLow = false;
                Log.i(TAG, "checkAllInput: " + node + " = " + val.trim());
            }
        }
        String msg = allLow
                ? "所有输入GPIO均为0（全部被拉低，正常）"
                : "以下输入GPIO未被拉低或异常: " + notLowList + "\n" + sb;
        Log.i(TAG, "checkAllInput: " + msg);
        tvResult.setText(msg);
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }
}
